// @Author miaoqing
// @Date 2024/03/28 15:13:00
// @Desc
package logic

import (
	"core/component/function"
	"core/component/router"
	"runtime/debug"
	"sync"
)

var (
	rManager     *RoomManager
	rManagerOnce sync.Once
)

// RoomManager 房间管理器
type RoomManager struct {
	rooms         *sync.Map //map[uint64]*Room
	wg            sync.WaitGroup
	router        *router.Router
	removeChannel chan uint64
	msgChannel    chan interface{}
}

// RoomManager 构造
func RoomManagerGetMe() *RoomManager {
	rManagerOnce.Do(func() {
		rManager = &RoomManager{
			rooms:         &sync.Map{},
			router:        router.NewRouter(),
			removeChannel: make(chan uint64, 1024),
			msgChannel:    make(chan interface{}, 1024),
		}
		rManager.registerRMHandler()
		go rManager.loop()
	})
	return rManager
}

func (mgr *RoomManager) loop() {
	defer func() {
		if err := recover(); err != nil {
			function.WritePanic(string(debug.Stack()), err)
			return
		}
	}()
	for {
		select {
		case id := <-mgr.removeChannel:
			mgr.removeRoom(id)
		case msg := <-mgr.msgChannel:
			mgr.onMessage(msg.([]byte))
		}
	}
}

// CreateRoom 创建房间
func (m *RoomManager) createRoom(id uint64, typeID int32, playerID []uint64, randomSeed int64, logicServer string) (*Room, error) {
	r := newRoom(id, typeID, playerID, randomSeed, logicServer)
	m.rooms.Store(id, r)
	return r, nil
}

// GetRoom 获得房间
func (m *RoomManager) getRoom(id uint64) *Room {
	r, ok := m.rooms.Load(id)
	if !ok {
		return nil
	}
	return r.(*Room)
}

// RoomNum 获得房间数量
func (m *RoomManager) RoomNum() int {
	return int(function.CalcSyncMapLen(m.rooms))
}

// Stop 停止
func (m *RoomManager) Stop() {
	m.rooms.Range(func(key, value any) bool {
		r, ok := value.(*Room)
		if !ok {
			return true
		}
		r.Stop()
		return true
	})
	m.rooms = &sync.Map{}
}

func (mgr *RoomManager) removeRoom(id uint64) {
	mgr.rooms.Delete(id)
}

func (mgr *RoomManager) onMessage(data []byte) {
	mgr.router.Route(data)
}
